package
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.utils.ByteArray;
	
	public class CurvingRoad extends Sprite
	{
		protected var bmp:Bitmap;
		protected var bmd:BitmapData;
		protected var bgd:BitmapData;
		protected var holder:Sprite;
		
		protected var road:ByteArray = new ByteArray();
		protected var visibleRoad:Array = new Array();
		
		protected var dir:Point = new Point();
		protected var deltaDir:Point = new Point();
		protected var matrix:Matrix = new Matrix();
		protected var position:int = 0;
		
		protected var roadPiece1:Sprite;
		protected var roadPiece2:Sprite;
		
		protected const STEP_LENGTH:int = 20;
		protected const SEGMENTS:int = 50;
		
		public function get pos():int 
		{
			return position;
		}
		public function set pos(value:int):void
		{
			position = value;
			
			var i:int = (position/STEP_LENGTH) << 2;
			if(i < road.length)
			{
				if(i > 0)
				{
					road.position = i;
				}
				else
				{
					road.position = road.length + i%road.length;
				}
			}
			else road.position = i%road.length;
			
			for( i=0; i<SEGMENTS; i++) 
			{
				if(road.position == road.length)
				{
					road.position = 0;
				}
				
				visibleRoad[i] = road.readInt();
			}
			
			draw();
		}
		public function resetPos():void
		{
			var i:int = (position/STEP_LENGTH) << 2;
			if(i > road.length || i < 0)
			{
				i = i%road.length;
				position = position%STEP_LENGTH + i;
			}
		}
		
		public function CurvingRoad(_bgd:BitmapData)
		{
			this.bgd = _bgd;
			
			this.roadPiece1 = drawRoadPiece(true);
			this.roadPiece2 = drawRoadPiece(false);
			
			bmd = new BitmapData(1000,1000,true,0x00000000);
			bmp = new Bitmap(bmd);
			this.addChild(bmp);
			
			var degrees:int = 0;
			var i:int
			var delta:int
			road.writeInt(degrees);
			
			i = 50;
			delta = 0;
			for( ; i>0; i--)
			{
				degrees += delta;
				road.writeInt(degrees);
			}
			for(var j:int=0; j<20; j++)
			{
				i = 60;
				delta = Math.random()*6-3;
				for( ; i>0; i--)
				{
					degrees += delta;
					road.writeInt(degrees);
				}
//				degrees = degrees%360;
//				if(degrees < 0) degrees = 360 + degrees;
			}
			i = degrees%360;
			delta = -1;
			for( ; i>0; i--)
			{
				degrees += delta;
				road.writeInt(degrees);
			}
			
			this.pos = 0;
		}
		
		protected function drawRoadPiece(bool:Boolean):Sprite
		{
			var sprite:Sprite = new Sprite();
			var matrix:Matrix = new Matrix();
			if(bool)
			{
				matrix.tx = 34;
			}
//			sprite.graphics.beginBitmapFill(bgd, matrix, true,true);
//			sprite.graphics.drawRect(-500,-15,1000,32);
			sprite.graphics.beginFill(0x303030,1);
//			sprite.graphics.lineStyle(1,0xFFFFFF);
			sprite.graphics.drawRect(-40,-10,80,27);
			sprite.graphics.endFill();
			if(bool)
			{
				sprite.graphics.lineStyle(5,0xFFFF00);
				sprite.graphics.moveTo(0,0);
				sprite.graphics.lineTo(0,8);
			}
			
			return sprite;
		}
		
		protected function onEnter(e:Event=null):void
		{
			step();
			draw();
		}
		
		protected function step():void
		{
			if(road.position == road.length)
			{
				road.position = 0;
			}
			
			var i:int = road.readInt();
			
			visibleRoad.shift();
			visibleRoad[SEGMENTS-1] = i;
		}
		
		protected function draw():void
		{
			dir.x = dir.y = 0;
			var first:int = visibleRoad[0];
			var next:int = 0;
			var i:int=1;
			var offY:int = position%STEP_LENGTH;
			var perc:Number = offY/STEP_LENGTH;
			
			var angle:Number = (visibleRoad[1]-first)*perc;
			
			bmd.fillRect(bmd.rect, 0x00000000);
			for( ; i<SEGMENTS; i++)
			{
				next = visibleRoad[i];
				deltaDir.x = Math.sin(Math.PI*(first-next+angle)/180);
				deltaDir.y = Math.cos(Math.PI*(first-next+angle)/180);
				dir.x += deltaDir.x*STEP_LENGTH;
				dir.y += deltaDir.y*STEP_LENGTH;
				matrix.a = deltaDir.y;
				matrix.b = deltaDir.x;
				matrix.c = -deltaDir.x;
				matrix.d = deltaDir.y;
				matrix.tx = 500+dir.x;
				matrix.ty = 1000-dir.y+offY;
				
				if(((road.position>>2)+i)&1) { bmd.draw(this.roadPiece1, matrix); }
				else { bmd.draw(this.roadPiece2, matrix); }
			}
		}
	}
}